﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Xml;
using System.IO;
using System.Collections;
using System.Text.RegularExpressions;

namespace WebDictionary
{
    public class WebDicManage
    {
        private XmlDocument WDDoc = null;
        private string WebDicFileName = "";
        private string ErrorMsg = "";

        private bool isLoad = false;

        private XmlNodeList WordList = null;

        public WebDicManage()
        {
        }

        public bool IsLoad()
        {
            return isLoad;
        }
        // Load a web dictionary, should be in .dctx format
        public bool LoadWebDic(string fn)
        {
            try
            {
                if (WDDoc == null)
                    WDDoc = new XmlDocument();
                WebDicFileName = fn;
                WDDoc.Load(WebDicFileName);
                isLoad = true;
                return true;
            }
            catch (Exception e)
            {
                ErrorMsg = e.ToString();
                return false;
            }
        }

        public bool NewWebDic()
        {
            bool ret = LoadWebDic(@"template.wdt");
            WebDicFileName = "";
            isLoad = true;
            return ret;
        }

        public bool IsNew()
        {
            if (WebDicFileName == "")
                return true;
            return false;
        }
        //===============================
        public bool SaveWebDic(string strFN)
        {
            WebDicFileName = strFN;
            return SaveWebDic();

        }
        public string GetDicName()
        {
            return WebDicFileName;
        }
        //==========================================
        public bool SaveWebDic()
        {
            try
            {
                if (WDDoc != null)
                {
                    if (WebDicFileName == "")
                        return false;

                    WDDoc.Save(WebDicFileName);
                    return true;
                }
            }
            catch (Exception e)
            {
                ErrorMsg = e.ToString();
                return false;
            }
            return false;
        }
        public bool Close()
        {
            return true;
        }
        //================================================
        //set the DictionaryGUID
        public bool SetDictinaryGUID(string strGUID)
        {
            return SetElement("ns1:DictionaryGUID", strGUID);
        }
        //Get the dictionary GUID
        public string GetDictinaryGUID()
        {
            return GetElement("ns1:DictionaryGUID");
        }
        //======================================================
        //set the Dictionary Version
        public bool SetDictinaryVersion(string strVer)
        {
            
            return SetElement("ns1:DictionaryVersion", strVer);

        }
        //Get the dictionary version
        public string GetDictinaryVersion()
        {
            return GetElement("ns1:DictionaryVersion");
        }

        //================================================
        //set the SourceURL
        public bool SetDictinarySourceURL(string strSourceURL)
        {
            return SetElement("ns1:SourceURL", strSourceURL);
        }
        //Get the dictionary GUID
        public string GetDictinarySourceURL()
        {
            return GetElement("ns1:SourceURL");
        }


        //==================================================

        //set the Dictionary CHS short name
        public bool SetDictinaryCHSShortname(string strShortName)
        {
            return SetDicInfoElement("ns1:ShortName", strShortName, "zh-cn");
            
        }
        //Get the Dictionary CHS short name
        public string GetDictinaryCHSShortname()
        {
            return GetDicInfoElement("ns1:ShortName", "zh-cn");
        }
        //----------------------------------------

        //set the Dictionary ENG short name
        public bool SetDictinaryENGShortname(string strShortName)
        {

            return SetDicInfoElement("ns1:ShortName", strShortName, "en-us");
        }
        //Get the Dictionary CHS short name
        public string GetDictinaryENGShortname()
        {
            return GetDicInfoElement("ns1:ShortName", "en-us");
        }

        //==================================================

        //set the Dictionary CHS long name
        public bool SetDictinaryCHSLongname(string strLongname)
        {
            return SetDicInfoElement("ns1:LongName", strLongname, "zh-cn");
        }
        //Get the Dictionary CHS long name
        public string GetDictinaryCHSLongname()
        {
            return GetDicInfoElement("ns1:LongName", "zh-cn");
        }
        //----------------------------------------

        //set the Dictionary ENG long name
        public bool SetDictinaryENGLongname(string strLongname)
        {
            return SetDicInfoElement("ns1:LongName", strLongname, "en-us");
        }
        //Get the Dictionary ENG long name
        public string GetDictinaryENGLongname()
        {

            return GetDicInfoElement("ns1:LongName", "en-us");
        }

        //==================================================

        //set the Dictionary CHS Description
        public bool SetDictinaryCHSDescription(string strDescription)
        {

            return SetDicInfoElement("ns1:Description", strDescription, "zh-cn");
        }
        //Get the Dictionary CHS Description
        public string GetDictinaryCHSDescription()
        {
            return GetDicInfoElement("ns1:Description", "zh-cn");
        }
        //----------------------------------------

        //set the Dictionary ENG Description
        public bool SetDictinaryENGDescription(string strDescription)
        {
            return SetDicInfoElement("ns1:Description", strDescription, "en-us");
        }
        //Get the Dictionary CHS short name
        public string GetDictinaryENGDescription()
        {
            return GetDicInfoElement("ns1:Description", "en-us");
        }

        //==================================================

        //set the Dictionary CHS Copyright
        public bool SetDictinaryCHSCopyright(string strCopyright)
        {
            return SetDicInfoElement("ns1:Copyright", strCopyright, "zh-cn");
        }
        //Get the Dictionary CHS Copyright
        public string GetDictinaryCHSCopyright()
        {
            return GetDicInfoElement("ns1:Copyright", "zh-cn");
        }
        //----------------------------------------

        //set the Dictionary ENG Copyright
        public bool SetDictinaryENGCopyright(string strCopyright)
        {
            return SetDicInfoElement("ns1:Copyright", strCopyright, "en-us");
        }
        //Get the Dictionary CHS short name
        public string GetDictinaryENGCopyright()
        {
            return GetDicInfoElement("ns1:Copyright", "en-us");
        }
        //========================================================

        public void GetWordList()
        {
            try
            {
                if (WDDoc == null)
                {
                    throw new Exception(string.Format("please load web dictionary first"));
                }
                WordList = WDDoc.GetElementsByTagName(@"ns1:DictionaryEntry");

            }
            catch (Exception eee)
            {
                ErrorMsg = "GetWordList: " + eee.ToString();
            }
        }
        //-----------------------------------------------
        public int GetWordCount()
        {
            try
            {
                if (WordList == null)
                {
                    throw new Exception(string.Format("Please call GetWordList function first"));
                }
                return WordList.Count;

            }
            catch (Exception eee)
            {
                ErrorMsg = "GetWordCount: " + eee.ToString();
                return 0;
            }

        }
        //-------------------------------------------------
        public WDWord GetWord(int idx)
        {
            try
            {
                if (WordList == null)
                {
                    throw new Exception(string.Format("Please call GetFirstWord function first"));
                }
                if (WordList.Count > idx)
                {
                    return WordParse(WordList[idx]);
                }
                return null;

            }
            catch (Exception eee)
            {
                ErrorMsg = "GetWord: " + eee.ToString();
                return null;
            }
        }
        //----------------------------------------------
        //parse a word content

        public WDWord WordParse(XmlNode WordNd)
        {
            try
            {
                if (WordNd == null)
                    return null;
                WDWord wdw = new WDWord();
                XmlNode TempNode = WordNd.FirstChild;
                while (TempNode != null)
                {
                    if (TempNode.Name == @"ns1:OutputString")
                    {
                        wdw.strWord = TempNode.InnerText;
                    }
                    if (TempNode.Name == @"ns1:InputString")
                    {
                        wdw.strPinYin = TempNode.InnerText;
                    }
                    TempNode = TempNode.NextSibling;
                }
                return wdw;
            }
            catch (Exception eee)
            {
                ErrorMsg = @"WordParse:" + eee.ToString();
                return null;
            }
        }


        //==================================================

        public void RemoveAllWord()
        {
            try
            {
                if (WDDoc == null)
                {
                    return;
                }
                XmlNodeList TempDic = WDDoc.GetElementsByTagName(@"ns1:Dictionary");

                if (TempDic.Count <= 0 || TempDic.Count > 1)
                {
                    throw new Exception(string.Format("the dictionary is broken"));

                }
                XmlNode TempNL = TempDic[0].FirstChild;
                while (TempNL != null)
                {
                    if (TempNL.Name == @"ns1:DictionaryEntry")
                    {
                        XmlNode tcurr = TempNL;
                        TempNL = TempNL.NextSibling;
                        TempDic[0].RemoveChild(tcurr);
                    }
                    else
                    {
                        TempNL = TempNL.NextSibling;
                    }
                }
            }
            catch (Exception e)
            {
                ErrorMsg = e.ToString();
                return;
            }

        }
        //------------------------------------------
        public bool InsertAWord(WDWord wdw)
        {
            if (wdw.strWord.Trim().Length == 0 || wdw.strPinYin.Trim().Length == 0)
                return false;

            try
            {
                if (WDDoc == null)
                {
                    throw new Exception(string.Format("please load web dictionary first"));
                }

                //if (WordExist(wdw, true))
                //    return true;

                XmlElement Elem = WDDoc.CreateElement(@"ns1", @"DictionaryEntry", @"http://www.microsoft.com/ime/dctx");

                XmlElement ElemPY = WDDoc.CreateElement(@"ns1", @"InputString", @"http://www.microsoft.com/ime/dctx");

                ElemPY.InnerText = wdw.strPinYin;

                XmlElement ElemWord = WDDoc.CreateElement(@"ns1", @"OutputString", @"http://www.microsoft.com/ime/dctx");

                XmlElement ElemExistFlag = WDDoc.CreateElement(@"ns1", @"Exist", @"http://www.microsoft.com/ime/dctx");
                ElemExistFlag.InnerText = "1";

                ElemWord.InnerText = wdw.strWord;
                Elem.AppendChild(ElemPY);
                Elem.AppendChild(ElemWord);
                Elem.AppendChild(ElemExistFlag);

                XmlElement dEle = WDDoc.DocumentElement;
                dEle.AppendChild(Elem);

                return true;
            }
            catch (Exception e)
            {
                ErrorMsg = e.ToString();
                return false;
            }


        }



        //--------------------------------
        //to detect whether a word is in current dictionary
        public bool WordExist(WDWord wdw, bool bflag)
        {
            if (wdw.strWord.Trim().Length == 0 || wdw.strPinYin.Trim().Length == 0)
                return false;


            try
            {
                if (WDDoc == null)
                {
                    throw new Exception(string.Format("please load web dictionary first"));
                }

                XmlNodeList TempDic = WDDoc.GetElementsByTagName(@"ns1:Dictionary");

                if (TempDic.Count <= 0 || TempDic.Count > 1)
                {
                    throw new Exception(string.Format("the dictionary is broken"));

                }
                XmlNode TempNL = TempDic[0].FirstChild;
                while (TempNL != null)
                {
                    if (TempNL.Name == @"ns1:DictionaryEntry")
                    {
                        bool bInputStr = false;
                        bool bOutputStr = false;
                        XmlNode tcurr = TempNL.FirstChild;
                        while (tcurr != null)
                        {
                            if (tcurr.Name == @"ns1:InputString" && tcurr.InnerText == wdw.strPinYin)
                                bOutputStr = true;
                            if (tcurr.Name == @"ns1:OutputString" && tcurr.InnerText == wdw.strWord)
                                bInputStr = true;

                            tcurr = tcurr.NextSibling;
                        }

                        if (bInputStr & bOutputStr)
                        {
                            if (bflag)
                            {
                                XmlElement ElemExistFlag = WDDoc.CreateElement(@"ns1", @"Exist", @"http://www.microsoft.com/ime/dctx");
                                ElemExistFlag.InnerText = "1";
                                TempNL.AppendChild(ElemExistFlag);
                            }
                            return true;
                        }
                    }
                    TempNL = TempNL.NextSibling;
                }
                return false;
            }
            catch (Exception e)
            {
                ErrorMsg = e.ToString();
                return false;
            }

        }
        //========================================
        //to detect whether a word is in current dictionary
        public bool WordExist(string strWord)
        {
            if (strWord.Trim().Length == 0)
                return false;

            try
            {
                if (WDDoc == null)
                {
                    throw new Exception(string.Format("please load web dictionary first"));
                }
                XmlNodeList TempNL = WDDoc.GetElementsByTagName("ns1:OutputString");
                if (TempNL.Count <= 0)
                {
                    return false;
                }
                foreach (XmlNode TempNode in TempNL)
                {

                    if (TempNode.InnerText.ToString() == strWord)
                        return true;
                }
                return false;
            }
            catch (Exception e)
            {
                ErrorMsg = e.ToString();
                return false;
            }

        }
        //=========================================
        public bool SetDicInfoElement(string TagName, string str, string EnCh)
        {
            try
            {
                if (WDDoc == null)
                {
                    throw new Exception(string.Format("please load web dictionary first\n"));
                }
                XmlNodeList TempNL = WDDoc.GetElementsByTagName(@"ns1:DictionaryInfo");
                if (TempNL.Count <= 0)
                {
                    throw new Exception(string.Format("the web dictionary is broken %s\n ", TagName));
                }
                XmlNode TempNode = null;
                foreach (XmlNode TNode in TempNL)
                {
                    if (TNode.Attributes["Language"].Value == EnCh)
                    {
                        TempNode = TNode;
                        break;
                    }
                }

                if (TempNode == null)
                {
                    throw new Exception(string.Format("Can't find %s, the dictionary is broken\n", TagName));
                }

                TempNode = TempNode.FirstChild;
                while (TempNode != null)
                {
                    if (TempNode.Name == TagName)
                    {
                        TempNode.InnerText = str;
                        return true;
                    }
                    TempNode = TempNode.NextSibling;
                }
                return false;
            }
            catch (Exception e)
            {
                ErrorMsg = e.ToString();
                return false;
            }
        }
        //=========================================
        public string GetDicInfoElement(string TagName, string EnCh)
        {
            try
            {
                if (WDDoc == null)
                {
                    throw new Exception(string.Format("please load web dictionary first\n"));
                }
                XmlNodeList TempNL = WDDoc.GetElementsByTagName(@"ns1:DictionaryInfo");
                if (TempNL.Count <= 0)
                {
                    throw new Exception(string.Format("the web dictionary is broken %s\n ", TagName));
                }
                XmlNode TempNode = null;
                foreach (XmlNode TNode in TempNL)
                {
                    if (TNode.Attributes["Language"].Value == EnCh)
                    {
                        TempNode = TNode;
                        break;
                    }
                }

                if (TempNode == null)
                {
                    throw new Exception(string.Format("Can't find %s, the dictionary is broken\n", TagName));
                }

                TempNode = TempNode.FirstChild;
                while (TempNode != null)
                {
                    if (TempNode.Name == TagName)
                    {
                        return TempNode.InnerText;
                    }
                    TempNode = TempNode.NextSibling;
                }
                return "";
            }
            catch (Exception e)
            {
                ErrorMsg = e.ToString();
                return "";
            }
        }
        //===========================================
        public bool SetElement(string TagName, string str)
        {
            try
            {
                if (WDDoc == null)
                {
                    throw new Exception(string.Format("please load web dictionary first"));
                }
                XmlNodeList TempNL = WDDoc.GetElementsByTagName(TagName);
                if (TempNL.Count <= 0)
                {
                    throw new Exception(string.Format("the web dictionary is broken %s: ", TagName));
                }
                XmlNode TempNode = TempNL[0].FirstChild;
                TempNode.InnerText = str;

                return true;
            }
            catch (Exception e)
            {
                ErrorMsg = e.ToString();
                return false;
            }
        }
        //Get the DictionaryGUID

        public string GetElement(string TagName)
        {
            try
            {
                if (WDDoc == null)
                {
                    throw new Exception(string.Format("please load web dictionary first"));
                }
                XmlNodeList TempNL = WDDoc.GetElementsByTagName(TagName);
                if (TempNL.Count <= 0)
                {
                    throw new Exception(string.Format("the web dictionary is broken %s: ", TagName));
                }
                XmlNode TempNode = TempNL[0].FirstChild;
                return TempNode.InnerText.ToString();
            }
            catch (Exception e)
            {
                ErrorMsg = e.ToString();
                return "";
            }
        }

        //==========================================
        //retired
        public void RemoveUnexistWord()
        {
            try
            {
                if (WDDoc == null)
                {
                    return;
                }
                XmlNodeList TempDic = WDDoc.GetElementsByTagName(@"ns1:Dictionary");

                if (TempDic.Count <= 0 || TempDic.Count > 1)
                {
                    throw new Exception(string.Format("the dictionary is broken"));

                }
                XmlNode TempNL = TempDic[0].FirstChild;
                while (TempNL != null)
                {
                    if (TempNL.Name == @"ns1:DictionaryEntry")
                    {
                        bool bExistFlag = false;

                        XmlNode tcurr = TempNL.FirstChild;
                        while (tcurr != null)
                        {
                            if (tcurr.Name == @"ns1:Exist")
                            {
                                TempNL.RemoveChild(tcurr);
                                bExistFlag = true;
                                break;
                            }
                            tcurr = tcurr.NextSibling;
                        }
                        tcurr = TempNL;
                        TempNL = TempNL.NextSibling;
                        if (!bExistFlag)
                        {
                            WDDoc.RemoveChild(tcurr);
                        }
                    }
                    else
                    {
                        TempNL = TempNL.NextSibling;
                    }
                }
            }
            catch (Exception e)
            {
                ErrorMsg = e.ToString();
                return;
            }

        }

    }
}
